from rest_framework import serializers
from django.db.models import Count

from .models import Project, ProjectAppeal
from utils.base import BaseSerializer
from apps.users.models import User
from apps.users.serializers import UserNameSerializers
from apps.interfaces.models import Api
from apps.tests.models import Case
from apps.envs.models import Module


class ProjectSerializer(BaseSerializer):

    url = serializers.CharField(required=False, allow_blank=True)
    user_names = serializers.SerializerMethodField()
    has_appeal = serializers.SerializerMethodField()
    env_number = serializers.SerializerMethodField()
    service_number = serializers.SerializerMethodField()
    plant_number = serializers.SerializerMethodField()
    module_number = serializers.SerializerMethodField()
    page_number = serializers.SerializerMethodField()
    element_number = serializers.SerializerMethodField()
    interface_number = serializers.SerializerMethodField()
    case_number = serializers.SerializerMethodField()
    ui_case_number = serializers.SerializerMethodField()
    api_case_number = serializers.SerializerMethodField()
    step_number = serializers.SerializerMethodField()
    tag_number = serializers.SerializerMethodField()
    suite_number = serializers.SerializerMethodField()
    script_number = serializers.SerializerMethodField()
    report_number = serializers.SerializerMethodField()
    module_detail = serializers.SerializerMethodField()
    tag_detail = serializers.SerializerMethodField()

    def get_tag_detail(self, obj):
        result = Case.objects.all().filter(project=obj, is_delete=False
                                           ).values('tag', 'tag__name').annotate(count=Count('tag'))
        for case_obj in result:
            case_obj['api_count'] = Case.objects.all().filter(project=obj, is_delete=False,
                                                              tag=case_obj['tag'], type=1).count()
            case_obj['ui_count'] = case_obj['count'] - case_obj['api_count']
        return result

    def get_module_detail(self, obj):
        result = Case.objects.all().filter(project=obj, is_delete=False
                                           ).values('module', 'module__name',
                                                    'module__plant__name').annotate(count=Count('module'))
        for case_obj in result:
            case_obj['api_count'] = Case.objects.all().filter(project=obj, is_delete=False,
                                                              module=case_obj['module'], type=1).count()
            case_obj['ui_count'] = case_obj['count'] - case_obj['api_count']
        return result

    def get_report_number(self, obj):
        return obj.report_set.filter(is_delete=False).count()

    def get_script_number(self, obj):
        return obj.pythonscript_set.filter(is_delete=False).count()

    def get_suite_number(self, obj):
        return obj.suite_set.filter(is_delete=False).count()

    def get_tag_number(self, obj):
        return obj.tag_set.filter(is_delete=False).count()

    def get_step_number(self, obj):
        return obj.step_set.filter(is_delete=False).count()

    def get_ui_case_number(self, obj):
        return obj.case_set.filter(is_delete=False, type=2).count()

    def get_api_case_number(self, obj):
        return obj.case_set.filter(is_delete=False, type=1).count()

    def get_case_number(self, obj):
        return obj.case_set.filter(is_delete=False).count()

    def get_interface_number(self, obj):
        return Api.objects.all().filter(module__project=obj, is_delete=False).count()

    def get_element_number(self, obj):
        return obj.element_set.filter(is_delete=False).count()

    def get_page_number(self, obj):
        return obj.page_set.filter(is_delete=False).count()

    def get_module_number(self, obj):
        return obj.module_set.filter(is_delete=False).count()

    def get_plant_number(self, obj):
        return obj.plant_set.filter(is_delete=False).count()

    def get_service_number(self, obj):
        return obj.service_set.filter(is_delete=False).count()

    def get_env_number(self, obj):
        return obj.env_set.filter(is_delete=False).count()

    def get_user_names(self, obj):
        return User.objects.all().filter(project=obj, is_delete=False).values('id', 'username')

    def get_has_appeal(self, obj):
        appeals = ProjectAppeal.objects.all().filter(project=obj, is_delete=False,
                                                     user=self.context['request'].user.id)
        if appeals:
            return appeals[0].status
        return True

    class Meta:
        model = Project
        fields = '__all__'


class ProjectAppealSerializer(BaseSerializer):

    project_name = serializers.CharField(source='project.name', read_only=True)
    project_create_by = serializers.CharField(source='project.create_by', read_only=True)
    project_create_by_id = serializers.IntegerField(source='project.create_by_id', read_only=True)
    user_name = serializers.CharField(source='user.name', read_only=True)

    class Meta:
        model = ProjectAppeal
        fields = '__all__'

